﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using XExcel.Validations;

namespace XExcel.Models
{
    [DebuggerDisplay("SheeetIndex = {SheeetIndex}, SheeetName = {SheeetName}, Rows = [{Rows}]")]
    class NpoiSheet<T> : IXSheet<T> where T : new()
    {
        public NpoiSheet(int sheeetIndex, string sheeetName, Dictionary<string, int> dictHeader)
        {
            SheeetIndex = sheeetIndex;
            SheeetName = sheeetName;
            this.dictHeader = dictHeader;
        }
        private List<IXRow<T>> rows = new List<IXRow<T>>();
        private List<Mapper> mappers = new List<Mapper>();
        private readonly Dictionary<string, int> dictHeader;
        public int SheeetIndex { get; }

        public string SheeetName { get; }

        public IList<IXRow<T>> Rows => rows.AsReadOnly();

        public TranferState State { get; private set; } = TranferState.Init;

        public void Transfer()
        {
            foreach(NpoiRow<T> row in rows)
            {
                row.Transfer(mappers);
            }
            if(rows.All(x => x.State == TranferState.Success))
            {
                State = TranferState.Success;
            }
            else
            {
                State = TranferState.Fail;
            }
        }

        public void Add(IXRow<T> row)
        {
            rows.Add(row);
        }

        public IXSheet<T> Map(string propName, string colName, Func<IXCell, object> convertor)
        {
            return Map(propName, colName, convertor, null);
        }

        public IXSheet<T> Map(string propName, string colName, IValidate validate)
        {
            return Map(propName, colName, null, validate);
        }

        public IXSheet<T> Map(string propName, string colName, Func<IXCell, object> convertor, IValidate validate)
        {
            if(!mappers.Any(x => x.PropertyName == propName))
            {
                mappers.Add(new Mapper { ColumnName = colName, PropertyName = propName, Convertor = convertor, Validate = validate });
            }
            return this;
        }

        public int GetColumnIndex(string colName)
        {
            if(dictHeader?.TryGetValue(colName, out int colIndex) == true)
            {
                return colIndex;
            }
            return -1;
        }
    }
}